local extension = Package:new("personal")

extension.extensionName = "tangshui"

local U = require "packages/utility/utility"

Fk:loadTranslationTable{
  ["personal"] = "自用",
}

local zhoubuyi = General(extension, "personal__zhoubuyi", "wei", 3)
local shijiz = fk.CreateTriggerSkill{
  name = "personal_shijiz",
  anim_type = "support",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and target.phase == Player.Finish and not target:isNude() then
      return #player.room.logic:getActualDamageEvents(1, function(e) return e.data[1].from == target end) == 0
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local mark = player:getMark("shijiz_names")
    if type(mark) ~= "table" then
      mark = U.getAllCardNames("t")
      room:setPlayerMark(player, "shijiz_names", mark)
    end
    local used = player:getTableMark("@$shijiz")
    local all_names, names = {}, {}
    for _, name in ipairs(mark) do
      local card = Fk:cloneCard(name)
      card.skillName = self.name
      if target:canUse(card) and not target:prohibitUse(card) then
        table.insert(all_names, name)
        if not table.contains(used, name) then
          table.insert(names, name)
        end
      end
    end
    local choices = U.askForChooseCardNames(room, player, names, 1, 1, self.name, "#shijiz-invoke::"..target.id, all_names, true)
    if #choices == 1 then
      self.cost_data = {tos = {target.id}, choice = choices[1]}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cardName = self.cost_data.choice
    room:addTableMark(player, "@$shijiz", cardName)
    local success, dat = room:askForUseActiveSkill(target, "shijiz_viewas", "#shijiz-use:::"..cardName, true,
    {shijiz_name = cardName})
    if dat then
      local card = Fk:cloneCard(cardName)
      card:addSubcards(dat.cards)
      card.skillName = self.name
      room:useCard{
        from = target.id,
        tos = table.map(dat.targets, function(p) return {p} end),
        card = card,
      }
    end
  end,
}
local shijiz_viewas = fk.CreateViewAsSkill{
  name = "personal_shijiz_viewas",
  card_filter = function(self, to_select, selected)
    return #selected == 0
  end,
  view_as = function(self, cards)
    if #cards ~= 1 then return end
    local card = Fk:cloneCard(self.shijiz_name)
    card:addSubcard(cards[1])
    card.skillName = "personal_shijiz"
    return card
  end,
}
local shijiz_prohibit = fk.CreateProhibitSkill{
  name = "#personal_shijiz_prohibit",
  is_prohibited = function(self, from, to, card)
    return card and from == to and table.contains(card.skillNames, "personal_shijiz")
  end,
}
local silun = fk.CreateTriggerSkill{
  name = "personal_silun",
  anim_type = "masochism",
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:drawCards(4, self.name)
    for i = 1, 4, 1 do
      if player.dead or player:isNude() then return end
      local _, dat = room:askForUseActiveSkill(player, "silun_active", "#silun-card:::" .. tostring(i), false)
      local card_id = dat and dat.cards[1] or player:getCardIds("he")[1]
      local choice = dat and dat.interaction or "Top"
      local reset_self = room:getCardArea(card_id) == Card.PlayerEquip
      if choice == "Field" then
        local to = room:getPlayerById(dat.targets[1])
        local card = Fk:getCardById(card_id)
        if card.type == Card.TypeEquip then
          room:moveCardTo(card, Card.PlayerEquip, to, fk.ReasonPut, "silun", "", true, player.id)
          if not to.dead then
            to:reset()
          end
        elseif card.sub_type == Card.SubtypeDelayedTrick then
          -- FIXME : deal with visual DelayedTrick
          room:moveCardTo(card, Card.PlayerJudge, to, fk.ReasonPut, "silun", "", true, player.id)
        end
      else
        local drawPilePosition = 1
        if choice == "Bottom" then
          drawPilePosition = -1
        end
        room:moveCards({
          ids = {card_id},
          from = player.id,
          toArea = Card.DrawPile,
          moveReason = fk.ReasonPut,
          skillName = "silun",
          drawPilePosition = drawPilePosition,
          moveVisible = true
        })
      end
      if reset_self and not player.dead then
        player:reset()
      end
    end
  end,
}
local silun_active = fk.CreateActiveSkill{
  name = "#personal_silun_active",
  mute = true,
  card_num = 1,
  max_target_num = 1,
  interaction = function()
    return UI.ComboBox {choices = {"Field", "Top", "Bottom"}}
  end,
  card_filter = function(self, to_select, selected, targets)
    if #selected == 0 then
      if self.interaction.data == "Field" then
        local card = Fk:getCardById(to_select)
        return card.type == Card.TypeEquip or card.sub_type == Card.SubtypeDelayedTrick
      end
      return true
    end
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    if #selected == 0 and self.interaction.data == "Field" and #selected_cards == 1 then
      local card = Fk:getCardById(selected_cards[1])
      local target = Fk:currentRoom():getPlayerById(to_select)
      if card.type == Card.TypeEquip then
        return target:hasEmptyEquipSlot(card.sub_type)
      elseif card.sub_type == Card.SubtypeDelayedTrick then
        return not target:isProhibited(target, card)
      end
    end
    return false
  end,
  feasible = function(self, selected, selected_cards)
    if #selected_cards == 1 then
      if self.interaction.data == "Field" then
        return #selected == 1
      else
        return true
      end
    end
  end,
}
Fk:addSkill(shijiz_viewas)
shijiz:addRelatedSkill(shijiz_prohibit)
Fk:addSkill(silun_active)
zhoubuyi:addSkill(shijiz)
zhoubuyi:addSkill(silun)
Fk:loadTranslationTable{
  ["personal__zhoubuyi"] = "周不疑",
  ["#zhoubuyi"] = "幼有异才",
  ["designer:personal_zhoubuyi"] = "拔都沙皇",
  ["illustrator:personal_zhoubuyi"] = "虫师",
  ["personal_shijiz"] = "十计",
  [":personal_shijiz"] = "一名角色的结束阶段，若其本回合未造成伤害，你可以声明一种普通锦囊牌（每种牌名限一次），其可以将一张牌当你声明的牌使用"..
  "（不能指定其为目标）。",
  ["personal_silun"] = "四论",
  [":personal_silun"] = "当你受到伤害后，你可以摸四张牌，然后将四张牌依次置于场上、牌堆顶或牌堆底，若此牌为你装备区里的牌，你复原武将牌，"..
  "若你将装备牌置于一名角色装备区，其复原武将牌。",

  ["$personal_shijiz1"] = "哼~区区十丈之城，何须丞相图画。",
  ["$personal_shijiz2"] = "顽垒在前，可依不疑之计施为。",
  ["$personal_silun1"] = "习守静之术，行务时之风。",
  ["$personal_silun2"] = "纵笔瑞白雀，满座尽高朋。",
  ["~personal__zhoubuyi"] = "人心者，叵测也。",
}

local xushao = General(extension, "personal__xushao", "qun", 3)
---@param player ServerPlayer
local addFangkeSkill = function(player, skillName)
  local room = player.room
  local skill = Fk.skills[skillName]
  if (not skill) or skill.lordSkill or skill.switchSkillName
    or skill.frequency > 3 -- 锁定技=3 后面的都是特殊标签
    or player:hasSkill(skill, true) then
    return
  end

  local fangke_skills = player:getMark("js_fangke_skills")
  if fangke_skills == 0 then fangke_skills = {} end
  table.insert(fangke_skills, skillName)
  room:setPlayerMark(player, "js_fangke_skills", fangke_skills)

  --[[
  -- room:handleAddLoseSkills(player, skillName, nil, false)
  player:doNotify("AddSkill", json.encode{ player.id, skillName })

  if skill:isInstanceOf(TriggerSkill) or table.find(skill.related_skills,
    function(s) return s:isInstanceOf(TriggerSkill) end) then
    player:doNotify("AddSkill", json.encode{ player.id, skillName, true })
  end

  if skill.frequency ~= Skill.Compulsory then
  end
  --]]

  player:addFakeSkill(skill)
  player:prelightSkill(skill.name, true)
  skill:onAcquire(player)
end

---@param player ServerPlayer
---@param general General
local function addFangke(player, general, addSkill)
  local room = player.room
  room:addTableMarkIfNeed(player, "@&js_fangke", general.name)

  if not addSkill then return end
  for _, s in ipairs(general.skills) do
    addFangkeSkill(player, s.name)
  end
  for _, sname in ipairs(general.other_skills) do
    addFangkeSkill(player, sname)
  end
end

local banned_fangke = {
  "starsp__xiahoudun",  -- 原因：无敌
  "shichangshi",   -- 原因：变将与休整
  "godjiaxu", "zhangfei","js__huangzhong", "liyixiejing", "olz__wangyun", "yanyan", "duanjiong", "wolongfengchu", "wuanguo",
  "os__wangling", -- 原因：没有可用技能
  "js__pangtong", "os__xia__liubei", -- 原因：发动技能逻辑缺陷
}

local yingmen = fk.CreateTriggerSkill{
  name = "personal_yingmen",
  events = {fk.GameStart, fk.TurnStart},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, _)
    if event == fk.GameStart then
      return player:hasSkill(self)
    else
      return target == player and player:hasSkill(self) and #player:getTableMark("@&js_fangke") < 3
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local exclude_list = table.map(room.players, function(p)
      return p.general
    end)
    table.insertTable(exclude_list, banned_fangke)
    for _, p in ipairs(room.players) do
      local deputy = p.deputyGeneral
      if deputy and deputy ~= "" then
        table.insert(exclude_list, deputy)
      end
    end

    local m = player:getMark("@&js_fangke")
    local n = 3
    if event ~= fk.GameStart then
      n = 3 - #player:getTableMark("@&js_fangke")
    end
    local generals = table.random(room.general_pile, n)
    for _, g in ipairs(generals) do
      addFangke(player, Fk.generals[g], player:hasSkill("js__pingjian", true))
    end
  end,

  refresh_events = {fk.SkillEffect},
  can_refresh = function (self, event, target, player, data)
    return target == player and player:getMark("js_fangke_skills") ~= 0 and
      table.contains(player:getMark("js_fangke_skills"), data.name)
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    for _, s in ipairs(data.related_skills) do
      if s:isInstanceOf(StatusSkill) then
        room:addSkill(s)
      end
    end
  end,
}

xushao:addSkill(yingmen)

xushao:addSkill("js__pingjian")
Fk:loadTranslationTable{
  ["personal__xushao"] = "许劭",
  ["#personal__xushao"] = "识人读心",
  ["cv:personal__xushao"] = "樰默",
  ["illustrator:personal__xushao"] = "凡果",

  ["personal_yingmen"] = "盈门",
  [":personal_yingmen"] = "锁定技，游戏开始时，你在剩余武将牌堆中随机获得三张武将牌置于你的武将牌上，称为“访客”；回合开始前，若你的“访客”数少于三张，"..
  "则你从剩余武将牌堆中将“访客”补至三张。",

  --CV：樰默
  ["$personal_yingmen1"] = "韩侯不顾？德高，门楣自盈。",
  ["$personal_yingmen2"] = "贫而不阿，名广，胜友满座。",
  ["~personal__xushao"] = "运去朋友散，满屋余风雨……",
}

local xuelingyun = General(extension, "personal__xuelingyun", "wei", 3, 3, General.Female)

Fk:loadTranslationTable{
  ["personal__xuelingyun"] = "薛灵芸",
}

xuelingyun:addSkill("siqi")

local qiaozhi = fk.CreateActiveSkill{
  name = "personal_qiaozhi",
  anim_type = "drawcard",
  card_num = 1,
  target_num = 0,
  prompt = "#qiaozhi-active",
  can_use = function (self, player, card, extra_data)
    return player:usedSkillTimes(self.name) < 1
  end,
  card_filter = function(self, to_select, selected)
    return #selected == 0 and not Self:prohibitDiscard(Fk:getCardById(to_select))
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:throwCard(effect.cards, self.name, player, player)
    if player.dead then return end
    local cards = U.turnOverCardsFromDrawPile(player, 2, self.name)
    local id = room:askForCardChosen(player, player, {
      card_data = {
        { self.name, cards }
      }
    }, self.name, "#qiaozhi-choose")
    room:obtainCard(player, id, true, fk.ReasonJustMove, player.id, self.name, "@@qiaozhi-inhand")
    room:cleanProcessingArea(cards, self.name)
  end,
}

local qiaozhi_invalidity = fk.CreateInvaliditySkill {
  name = "#qiaozhi_invalidity",
  invalidity_func = function(self, from, skill)
    return skill == qiaozhi and not table.every(from:getCardIds(Player.Hand), function (id)
      return Fk:getCardById(id, true):getMark("@@qiaozhi-inhand") == 0
    end)
  end
}

qiaozhi:addRelatedSkill(qiaozhi_invalidity)
xuelingyun:addSkill(qiaozhi)

Fk:loadTranslationTable{
  ["personal_qiaozhi"] = "巧织",
  [":personal_qiaozhi"] = "出牌阶段限一次，你可弃置一张牌，你亮出牌堆顶的两张牌，获得其中的一张牌。此技能于你以此法得到的牌从你的手牌区离开之前无效。",
}

local simazhao = General(extension, "personal__simazhao", "jin", 3)

local zhaoxin = fk.CreateTriggerSkill{
  name = "personal_zhaoxin",
  anim_type = "control",
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player == target and not player:isKongcheng()
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#personal_zhaoxin-ask")
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:showCards(player.player_cards[Player.Hand])
    local targets = table.map(table.filter(room:getOtherPlayers(player, false), function(p)
      return (p:getHandcardNum() <= player:getHandcardNum()) end), Util.IdMapper)
    if #targets > 0 then
      local to = room:getPlayerById(room:askForChoosePlayers(player, targets, 1, 1, "#personal_zhaoxin-choose", self.name, false)[1])
      U.swapHandCards(room, player, player, to, self.name)
    end
  end,
}
zhaoxin.isHiddenSkill = true

simazhao:addSkill(zhaoxin)
simazhao:addSkill("ld__suzhi")

Fk:loadTranslationTable{
  ["personal__simazhao"] = "司马昭",
  ["#personal__simazhao"] = "嘲风开天",
  ["designer:personal__simazhao"] = "韩旭",
  ["illustrator:personal__simazhao"] = "凝聚永恒",

  ["personal_zhaoxin"] = "昭心",
  [":personal_zhaoxin"] = "隐匿，当你受到伤害后，你可展示所有手牌，然后与一名手牌数不大于你的角色交换手牌。",
  ["#personal_zhaoxin-ask"] = "昭心：你可以展示所有手牌，然后与一名手牌数不大于你的角色交换手牌",
  ["#personal_zhaoxin-choose"] = "昭心：选择一名手牌数不大于你的角色，与其交换手牌",

  ["$personal_zhaoxin1"] = "行明动正，何惧他人讥毁。",
  ["$personal_zhaoxin2"] = "大业之举，岂因宵小而动？",

  ["~personal_  _simazhao"] = "千里之功，只差一步了……",
}


return extension